﻿#include "WRWorkServiceListModel.h"
#include "../WRSoft-Working-Common/WRWorkServiceUuids.h"
#include "../WRSoft-Working-Common/WRWorkDomainChangeEvent.h"
#include "../WRSoft-Working-Common/WRWorkObjectStatusChangeEvent.h"

#include <QThread>
#include <QThreadPool>
#include <QCoreApplication>

//初始化工作服务列表项目。
WRWorkServiceListEntry::WRWorkServiceListEntry(int index, WRWorkObject* target)
{
    m_index = index;
    m_status = WRWorkStatus::Unknown;
    m_target = target;
    m_uuid = target->uuid().toString();
    m_switchDealer = 0;
    m_statusSource = 0;
    if (!target->local())
    {
        m_controllable = !target->identify(WRWorkLocalControlServiceType);
    }
    else
    {
        m_controllable = true;
    }
}
//清理当前对象所占用的相关资源。
WRWorkServiceListEntry::~WRWorkServiceListEntry(void)
{
    //add code here
}

//执行初始化。
void WRWorkServiceListEntry::initilize(void)
{
    m_switchDealer = m_target->queryTaskDealer(WRWorkSwitchDealer);
    m_statusSource = m_target->queryStateSource(WRWorkStatusSource);
}

//设置为活动。
void WRWorkServiceListEntry::activate(void)
{
    if (m_statusSource)
    {
        m_statusSource->addHandler(this);
    }
}
//设置为不活动。
void WRWorkServiceListEntry::inactivate(void)
{
    if (m_statusSource)
    {
        m_statusSource->removeHandler(this);
    }
}

//当状态改变后调用此方法。
void WRWorkServiceListEntry::doProcess(const void*)
{
    //add code here
}

//初始化工作服务列表项目。
WRWorkLocalServiceListEntry::WRWorkLocalServiceListEntry(int index, WRWorkObject* target, WRWorkServiceListModel* parent)
    : WRWorkServiceListEntry(index, target)
{
    m_parent = parent;
    initilize();
}
//当状态改变后调用此方法。
void WRWorkLocalServiceListEntry::doProcess(const void* value)
{
    QCoreApplication::postEvent(m_parent, new WRWorkObjectStatusChangeEvent(m_index, m_target, *(const WRWorkStatus*)value));
}

//初始化工作服务列表项目。
WRWorkRemoteServiceListEntry::WRWorkRemoteServiceListEntry(int index, WRWorkObject* target, WRWorkRemoteServiceListArray* parent)
    : WRWorkServiceListEntry(index, target)
{
    m_parent = parent;
}
//当状态改变后调用此方法。
void WRWorkRemoteServiceListEntry::doProcess(const void* value)
{
    QCoreApplication::postEvent(m_parent, new WRWorkObjectStatusChangeEvent(m_index, m_target, *(const WRWorkStatus*)value));
}

//初始化当前数组。
WRWorkRemoteServiceListArray::WRWorkRemoteServiceListArray(WRWorkServiceListModel* parent, WRWorkSession* session, const WRArray<WRWorkObject*>& items)
    : m_list(items.count()), m_init(true)
{
    m_parent = parent;
    m_session = session;
    m_session->addRef();
    for(WRu i = 0, l = items.count(); i < l; ++i)
    {
        WRWorkServiceListEntry* item = new WRWorkRemoteServiceListEntry((WR32s)i, items[i], this);
        m_list[i] = item;
    }
}
//释放当前对象。
WRWorkRemoteServiceListArray::~WRWorkRemoteServiceListArray(void)
{
    for(WRu i = 0, l = m_list.count(); i < l; ++i)
    {
        WRWorkServiceListEntry* item = m_list[i];
        delete item;
    }
    m_session->release();
}

//线程池执行方法。
void WRWorkRemoteServiceListArray::init(void)
{
    for(WRu i = 0, l = m_list.count(); i < l; ++i)
    {
        WRWorkServiceListEntry* item = m_list[i];

        item->initilize();

        m_mutex.lock();
        if (m_parent)
        {
            item->activate();
            m_mutex.unlock();
        }
        else
        {
            for(WRu j = 0; j < i; ++j)
            {
                m_list[j]->inactivate();
            }
            m_mutex.unlock();
            deleteLater();
            return;
        }
    }
    m_mutex.lock();
    m_init = false;
    if (!m_parent)
    {
        for(WRu i = 0, l = m_list.count(); i < l; ++i)
        {
            m_list[i]->inactivate();
        }
        deleteLater();
    }
    m_mutex.unlock();
}

//处理事件。
bool WRWorkRemoteServiceListArray::event(QEvent *e)
{
    if (WRWorkObjectStatusChangeEvent::identify(e))
    {
        WRWorkObjectStatusChangeEvent* e2 = static_cast<WRWorkObjectStatusChangeEvent*>(e);
        if (m_parent)
        {
            m_parent->setStatus(e2->index(), e2->status());
        }
        return true;
    }
    return QObject::event(e);
}

//释放当前对象。
void WRWorkRemoteServiceListArray::release(void)
{
    QMutexLocker lck(&m_mutex);
    m_parent = 0;
    if (!m_init)
    {
        for(WRu i = 0, l = m_list.count(); i < l; ++i)
        {
            m_list[i]->inactivate();
        }
        deleteLater();
    }
}

//初始化工作服务列表模型。
WRWorkServiceListModel::WRWorkServiceListModel(const WRArray<WRWorkObject*>& objects)
    : m_list(objects.count()), m_array(0), m_domain(0), m_active(false), m_status(WRWorkDomain::Online)
{
    for(WRu i = 0, l = m_list.count(); i < l; ++i)
    {
        WRWorkServiceListEntry* item = new WRWorkLocalServiceListEntry((WR32s)i, objects[i], this);
        m_list[i] = item;
    }
}
//初始化工作服务列表模型。
WRWorkServiceListModel::WRWorkServiceListModel(WRWorkDomain* domain)
    : m_list(), m_array(0), m_domain(domain), m_active(false), m_status(WRWorkDomain::Closed)
{
    //add code here
}

//清理当前对象所占用的相关资源。
WRWorkServiceListModel::~WRWorkServiceListModel(void)
{
    if (!m_domain)
    {
        for(WRu i = 0, l = m_list.count(); i < l; ++i)
        {
            WRWorkServiceListEntry* item = m_list[i];
            delete item;
        }
    }
}

//设置为活动。
void WRWorkServiceListModel::activate(void)
{
    m_active = true;
    if (m_domain)
    {
        m_domain->add(this);
    }
    else
    {
        for(WRu i = 0, l = m_list.count(); i < l; ++i)
        {
            m_list[i]->activate();
        }
    }
}
//设置为不活动。
void WRWorkServiceListModel::inactivate(void)
{
    m_active = false;
    if (m_domain)
    {
        m_domain->remove(this);

        m_status = WRWorkDomain::Closed;
        emit statusChanged();

        if (m_list.count())
        {
            beginResetModel();
            m_list = WRArray<WRWorkServiceListEntry*>();
            endResetModel();
        }
        if (m_array)
        {
            m_array->release();
            m_array = 0;
        }
    }
    else
    {
        for(WRu i = 0, l = m_list.count(); i < l; ++i)
        {
            m_list[i]->inactivate();
        }
    }
}

//设置状态。
void WRWorkServiceListModel::setStatus(int index, WRWorkStatus value)
{
    if (m_active)
    {
        WRWorkServiceListEntry* item = m_list[index];
        if (item->status(value))
        {
            QModelIndex idx = createIndex(index, 0);
            emit dataChanged(idx, idx);
        }
    }
}

//当工作域状态改变后调用此方法，如果为在线状态，则存在会话，否则会话为0。
void WRWorkServiceListModel::onChanged(WRWorkDomain* domain, WRWorkDomain::Status status, WRWorkSession* session)
{
    QCoreApplication::postEvent(this, new WRWorkDomainChangeEvent(domain, status, session));
}

//处理事件。
bool WRWorkServiceListModel::event(QEvent *e)
{
    if (WRWorkObjectStatusChangeEvent::identify(e))
    {
        WRWorkObjectStatusChangeEvent* e2 = static_cast<WRWorkObjectStatusChangeEvent*>(e);
        if (m_active)
        {
            WRWorkServiceListEntry* item = m_list[e2->index()];
            if (item->status(e2->status()))
            {
                QModelIndex idx = createIndex(e2->index(), 0);
                emit dataChanged(idx, idx);
            }
        }
        return true;
    }
    else if (WRWorkDomainChangeEvent::identify(e))
    {
        WRWorkDomainChangeEvent* e2 = static_cast<WRWorkDomainChangeEvent*>(e);
        if (m_active)
        {
            m_status = e2->status();
            if (m_status == WRWorkDomain::Online)
            {
                const WRArray<WRWorkObject*>& items = e2->session()->filterObjects(WRWorkServiceType);
                if (items.count())
                {
                    m_array = new WRWorkRemoteServiceListArray(this, e2->session(), items);

                    beginResetModel();
                    m_list = m_array->list();
                    endResetModel();

                    QThreadPool::globalInstance()->start(new WRWorkRemoteServiceListThreadWorker(m_array));
                }
                emit statusChanged();
            }
            else
            {
                emit statusChanged();
                if (m_list.count())
                {
                    beginResetModel();
                    m_list = WRArray<WRWorkServiceListEntry*>();
                    endResetModel();
                }
                if (m_array)
                {
                    m_array->release();
                    m_array = 0;
                }
            }
        }
        return true;
    }
    return QAbstractItemModel::event(e);
}

//判断是否存在索引。
bool WRWorkServiceListModel::hasIndex(int row, int column, const QModelIndex &parent)
{
    if (parent.isValid())
    {
        return false;
    }
    return row >= 0 && row < (int)(m_list.count()) && column >= 0 && column < 4;
}

//获取索引。
QModelIndex WRWorkServiceListModel::index(int row, int column, const QModelIndex &parent) const
{
    if (parent.isValid())
    {
        return QModelIndex();
    }
    return createIndex(row, column);
}

//获取父索引。
QModelIndex WRWorkServiceListModel::parent(const QModelIndex &) const
{
    return QModelIndex();
}

//获取行数量。
int WRWorkServiceListModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid())
    {
        return 0;
    }
    return (int)m_list.count();
}
//获取列数量。
int WRWorkServiceListModel::columnCount(const QModelIndex &parent) const
{
    if (parent.isValid())
    {
        return 0;
    }
    return 4;
}

//判断是否具有子级。
bool WRWorkServiceListModel::hasChildren(const QModelIndex & parent) const
{
    if (parent.isValid())
    {
        return false;
    }
    return true;
}

//获取内容数据。
QVariant WRWorkServiceListModel::data(const QModelIndex &index, int role) const
{
    if (role == Qt::DisplayRole)
    {
        const WRWorkServiceListEntry* item = m_list[index.row()];
        switch (index.column()) {
        case 0:
            return item->statusString();
        case 1:
            return item->uuidString();
        case 2:
            return item->title();
        case 3:
            return item->description();
        default:
            return QVariant();
        }
    }
    return QVariant();
}
//获取标题数据。
QVariant WRWorkServiceListModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (role == Qt::DisplayRole)
    {
        if (orientation == Qt::Horizontal)
        {
            static QString statusString = QStringLiteral("状态");
            static QString uuidString = QStringLiteral("标识");
            static QString titleString = QStringLiteral("名称");
            static QString descriptionString = QStringLiteral("描述");

            switch (section) {
            case 0:
                return statusString ;
            case 1:
                return uuidString;
            case 2:
                return titleString;
            case 3:
                return descriptionString;
            default:
                return QVariant();
            }
        }
    }
    return QVariant();
}
